import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'
import * as Mui from '@material-ui/core';
import { useIntl } from 'react-intl';
import InfoLine from './InfoLine'
import { useChain } from './Chain';
import { useTokenGraph } from './TokenGraph';
import useContractChecker from './useContractChecker';
import { useWallet } from 'use-wallet';
import png1 from '../assets/images/1.png'
import png2 from '../assets/images/2.png'

import CloseIcon from '@material-ui/icons/Close';
import { Link } from './Router'
import '../styles/custom.css'

const MinePoolsContext = createContext()
const span = {
  width: '12px',
  height:'12px',
   backgroundColor: "#0091FF",  //驼峰法
   boxSizing: "border-box",
   display: 'inline-block',
   borderRadius:"50%"
};
export const useMinePools = () => useContext(MinePoolsContext)

export function MinePoolsProvider(props) {
  const chain = useChain()
  const _chain = useRef()
  const [minePools, setMinePools] = useState([])

  const check = useCallback(async (chain, pools) => {
    if (_chain.current !== chain) {
      return
    }

    try {
      const currentLength = await chain.contracts.mine.methods.poolLength().call()
      if (pools.length < currentLength) {
        for (let i = pools.length; i < currentLength; i++) {
          const { depositToken } = await chain.contracts.mine.methods.poolInfo(i).call()
          const theErc20Contract = chain.contracts.erc20.clone()
          theErc20Contract.options.address = depositToken
          const [name, symbol, decimals] = await Promise.all([
            theErc20Contract.methods.name().call(),
            theErc20Contract.methods.symbol().call(),
            theErc20Contract.methods.decimals().call()
          ]);
          pools.push({
            depositToken: {
              address: depositToken,
              name,
              symbol,
              decimals: parseInt(decimals) || 0,
              displayName: symbol || name || depositToken
            },
            index: i
          })
          localStorage.setItem(`minePools_${chain.id}_${chain.contracts.mine.options.address}`, JSON.stringify(pools))
          _chain.current === chain && setMinePools(pools.slice())
        }
      }
    } catch (err) {
      console.error(err)
    }

    setTimeout(check, 5000, chain, pools)
  }, [])

  useEffect(() => {
    if (chain) {
      _chain.current = chain
      const pools = localStorage.getItem(`minePools_${chain.id}_${chain.contracts.mine.options.address}`)
      setMinePools(pools ? JSON.parse(pools) : [])
      // check需要传入一个全新的对象
      check(chain, pools ? JSON.parse(pools) : [])
    } else {
      setMinePools([])
    }
    return () => { _chain.current = undefined }
  }, [chain, check])

  return (
    <MinePoolsContext.Provider value={minePools}>
      {props.children}
    </MinePoolsContext.Provider>
  )
}

function ActiveMineItem(props) {
  const { depositToken, index, onClose } = props
  const intl = useIntl()
  const chain = useChain()
  const tokenGraph = useTokenGraph()
  const wallet = useWallet()
  const daoToken = useMemo(() => chain ? chain.dao : {}, [chain])
  const [depositAmount, setDepositAmount] = useState('')
  const [withdrawAmount, setWithdrawAmount] = useState('')
  const depositBalance = useContractChecker({
    type: 'balance',
    id: depositToken.address,
    decimals: depositToken.decimals
  })
  const depositAllowance = useContractChecker({
    type: 'allowanceOfMine',
    id: depositToken.address,
    decimals: depositToken.decimals
  })
  const depositedAmount = useContractChecker({
    type: 'depositedAmount',
    id: index,
    decimals: depositToken.decimals
  })
  const pendingAmount = useContractChecker({
    type: 'pendingAmount',
    id: index,
    decimals: daoToken.decimals
  })

  let depositDisplay;
  if (!parseFloat(depositAmount)) {
    depositDisplay = {
      buttonText: intl.formatMessage({ defaultMessage: 'Pleace enter amount' }),
      buttonVariant: "contained",
      buttonDisabled: true
    }
  } else if (!depositBalance || !depositAllowance) {
    depositDisplay = {
      buttonText: intl.formatMessage({ defaultMessage: 'Loading...' }),
      buttonVariant: "contained",
      buttonDisabled: true
    }
  } else if (depositBalance.lt(depositAmount)) {
    depositDisplay = {
      buttonText: intl.formatMessage({ defaultMessage: 'Insufficient balance' }),
      buttonVariant: "contained",
      buttonDisabled: true
    }
  } else if (depositAllowance.lt(depositAmount)) {
    depositDisplay = {
      buttonText: intl.formatMessage({ defaultMessage: 'Approve {token}' }, {
        token: depositToken.displayName
      }),
      buttonVariant: "outlined",
      buttonOnClick: () => chain.approveToMine(wallet.account, depositToken.address),
    }
  } else {
    depositDisplay = {
      buttonText: intl.formatMessage({ defaultMessage: 'Deposit' }),
      buttonVariant: "contained",
      buttonOnClick: () => chain.depositToPool(wallet.account, index, depositAmount, depositToken.decimals),
    }
  }


  let withdrawDisplay;
  if (!parseFloat(withdrawAmount)) {
    withdrawDisplay = {
      buttonText: intl.formatMessage({ defaultMessage: 'Pleace enter amount' }),
      buttonVariant: "contained",
      buttonDisabled: true
    }
  } else if (!depositedAmount) {
    withdrawDisplay = {
      buttonText: intl.formatMessage({ defaultMessage: 'Loading...' }),
      buttonVariant: "contained",
      buttonDisabled: true
    }
  } else if (depositedAmount.lt(withdrawAmount)) {
    withdrawDisplay = {
      buttonText: intl.formatMessage({ defaultMessage: 'Insufficient balance' }),
      buttonVariant: "contained",
      buttonDisabled: true
    }
  } else {
    withdrawDisplay = {
      buttonText: intl.formatMessage({ defaultMessage: 'Withdraw' }),
      buttonVariant: "contained",
      buttonOnClick: () => chain.withdrawFromPool(wallet.account, index, withdrawAmount, depositToken.decimals),
    }
  }

  const displayName = useMemo(()=>{
    if (depositToken.address in tokenGraph.pairs) {
      const pair = tokenGraph.pairs[depositToken.address]
      return `LP(${tokenGraph.tokens[pair.token0].displayName}/${tokenGraph.tokens[pair.token1].displayName})`
    } else {
      return depositToken.displayName
    }
  }, [depositToken, tokenGraph])

  return (
    <>
      <Mui.DialogTitle disableTypography sx={{ position: 'relative' }}>
        <Mui.Typography variant="h6" component="div">
          {intl.formatMessage({ defaultMessage: 'Deposit {token}' }, {
            token: displayName
          })}
        </Mui.Typography>
        <Mui.IconButton
          onClick={onClose}
          sx={{
            position: 'absolute',
            right: 8,
            top: 8,
            color: (theme) => theme.palette.grey[500],
          }}
        >
          <CloseIcon />
        </Mui.IconButton>
      </Mui.DialogTitle>
      <Mui.DialogContent sx={{ pb: 3 }}>
        <Mui.Typography variant="subtitle1" component="div">
          {intl.formatMessage({ defaultMessage: 'Deposit' })}
        </Mui.Typography>
        <Mui.TextField
          label={intl.formatMessage({ defaultMessage: 'Amount' })}
          type="text"
          size="small"
          margin="normal"
          value={depositAmount}
          onChange={(e) => setDepositAmount(/^\d*\.?\d*$/.test(e.target.value) ? e.target.value : depositAmount)}
          fullWidth
          helperText={depositBalance && intl.formatMessage({ defaultMessage: 'Balance: {balance}' }, { balance: depositBalance.toFixed() })}
          sx={{ mt: 1 }}
          InputProps={{
            endAdornment: <Mui.InputAdornment position="end">
              {depositToken.displayName}
              <Mui.Button className="cn-custom-btn" sx={{ mr: '-12px' }} size="small" onClick={() => setDepositAmount(depositBalance.toFixed())} >
                {intl.formatMessage({ defaultMessage: 'Max' })}
              </Mui.Button>
            </Mui.InputAdornment>
          }}
          FormHelperTextProps={{
            sx: {
              overflow: 'hidden',
              textOverflow: 'ellipsis',
              whiteSpace: 'nowrap'
            }
          }}
        />
        <Mui.Button className="custom-btn" sx={{ mb: 1 }} size="small" fullWidth variant={depositDisplay.buttonVariant} onClick={depositDisplay.buttonOnClick} disabled={depositDisplay.buttonDisabled}>
          {depositDisplay.buttonText}
        </Mui.Button>
        <Mui.Typography variant="subtitle1" component="div">
          {intl.formatMessage({ defaultMessage: 'Claim' })}
        </Mui.Typography>
        <InfoLine
          name={intl.formatMessage({ defaultMessage: 'Claimable' })}
          value={pendingAmount ? pendingAmount.toFixed() : '–'}
          unit={daoToken.displayName}
        />
        <Mui.Button className="custom-btn" sx={{ mb: 1 }} size="small" fullWidth variant="outlined" onClick={() => chain.claimFromPool(wallet.account, index)} disabled={!pendingAmount || pendingAmount.eq(0)}>
          {intl.formatMessage({ defaultMessage: 'Claim' })}
        </Mui.Button>
        <Mui.Typography variant="subtitle1" component="div">
          {intl.formatMessage({ defaultMessage: 'Withdraw' })}
        </Mui.Typography>
        <Mui.TextField
          label={intl.formatMessage({ defaultMessage: 'Amount' })}
          type="text"
          size="small"
          margin="normal"
          value={withdrawAmount}
          onChange={(e) => setWithdrawAmount(/^\d*\.?\d*$/.test(e.target.value) ? e.target.value : withdrawAmount)}
          fullWidth
          helperText={depositedAmount && intl.formatMessage({ defaultMessage: 'Deposited: {deposited}' }, { deposited: depositedAmount.toFixed() })}
          sx={{ mt: 1 }}
          InputProps={{
            endAdornment: <Mui.InputAdornment position="end">
              {depositToken.displayName}
              <Mui.Button className="cn-custom-btn"  sx={{ mr: '-12px' }} size="small" onClick={() => setWithdrawAmount(depositedAmount.toFixed())} >
                {intl.formatMessage({ defaultMessage: 'Max' })}
              </Mui.Button>
            </Mui.InputAdornment>
          }}
          FormHelperTextProps={{
            sx: {
              overflow: 'hidden',
              textOverflow: 'ellipsis',
              whiteSpace: 'nowrap'
            }
          }}
        />
        <Mui.Button className="custom-btn" size="small" fullWidth variant={withdrawDisplay.buttonVariant} onClick={withdrawDisplay.buttonOnClick} disabled={withdrawDisplay.buttonDisabled}>
          {withdrawDisplay.buttonText}
        </Mui.Button>
      </Mui.DialogContent>
    </>
  )
}

function MineItem(props) {
  const { depositToken, index, handleDepositClick } = props
  const intl = useIntl()
  const chain = useChain()
  const tokenGraph = useTokenGraph()
  const daoToken = useMemo(() => chain ? chain.dao : {}, [chain])
  const outputPerBlock = useContractChecker({
    type: 'minedPerBlockByPool',
    id: index,
    decimals: daoToken.decimals
  })
  const totalDepositedAmount = useContractChecker({
    type: 'totalDepositedAmount',
    id: depositToken.address,
    decimals: depositToken.decimals
  })
  const depositedAmount = useContractChecker({
    type: 'depositedAmount',
    id: index,
    decimals: depositToken.decimals
  })
  const pendingAmount = useContractChecker({
    type: 'pendingAmount',
    id: index,
    decimals: daoToken.decimals
  })

  const displayName = useMemo(()=>{
    if (depositToken.address in tokenGraph.pairs) {
      const pair = tokenGraph.pairs[depositToken.address]
      return `LP(${tokenGraph.tokens[pair.token0].displayName}/${tokenGraph.tokens[pair.token1].displayName})`
    } else {
      return depositToken.displayName
    }
  }, [depositToken, tokenGraph])

  return (
    <Mui.Grid item width="100%" md={6} lg={4}>
      <Mui.Card  style={{boxShadow:'none'}} sx={{ maxWidth: 300, mx: 'auto' }}>
      <img src={png1} style={{width:'120px',height:'60px'}}></img>
 
       
         <Mui.CardContent sx={{ p: 3, mt: 'auto' }}>
          <Mui.Typography gutterBottom variant="h6" textAlign="center">
            <span style={{fontWeight:'bold'}}>LP(MDX/VIT)</span>
            
              </Mui.Typography>
              <div style={{color:'#ED1F7A',width:'140px',height:'26px',borderRadius:'25px',textAlign:'center',margin:'20px auto',border:'1px solid #ED1F7A '}}>APY：155.33%</div>
          <InfoLine
          style={{fontSize:'16px'}}
            name='TVL'
            value='$1,004,680,036'
            unit={intl.formatMessage({ defaultMessage: '{token}/block' }, {
              token: daoToken.displayName
            })}
          />
          <InfoLine
             style={{fontSize:'16px'}}
            name='Weekly rewards'
            value='1,395,480 VIT'
           
          />
          {/* <InfoLine
            name={intl.formatMessage({ defaultMessage: 'Total deposit' })}
            value={totalDepositedAmount ? totalDepositedAmount.toFixed() : '–'}
            unit={depositToken.displayName}
          /> */}
       
          <Mui.Grid container spacing={1}>
           
            <Mui.Grid style={{margin:'20px 0'}} item flexGrow={1}>
              <Mui.Button style={{height:'50px',width:'248px',borderRadius:'16px'}} className="custom-btn" fullWidth variant="contained" onClick={handleDepositClick}>
                {/* {intl.formatMessage({ defaultMessage: 'Deposit' })} */}
                select
              </Mui.Button>
            </Mui.Grid>
          </Mui.Grid>
        </Mui.CardContent>
      </Mui.Card>
    </Mui.Grid>
  )
}

export default function Mine() {
  const pools = useMinePools()
  const [activeMineItem, setActiveMineItem] = useState()

  return (
    <>
      <Mui.Container sx={{ p: 3 }}>
        <div style={{fontSize:'20px'}}><span style={span}></span> Liquidity Pool</div>
        <Mui.Grid style={{marginTop:'100px',textAlign:'center'}} container spacing={2}>
          {pools.map((pool) => <MineItem key={pool.index} {...pool} handleDepositClick={() => setActiveMineItem(pool)} />)}
        </Mui.Grid>
      </Mui.Container>
      <Mui.Dialog
        open={!!activeMineItem}
        onClose={() => setActiveMineItem()}
        maxWidth="xs"
        fullWidth
      >
        {activeMineItem && <ActiveMineItem onClose={() => setActiveMineItem()} {...activeMineItem} />}
      </Mui.Dialog>
    </>
  )
}